package com.yehun.utils;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by Genius on 2017/5/3 0003.
 */
public class AnnotationUtils {

    public static <T extends Annotation> T getAnnotation(JoinPoint point, Class<T> type) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        if (method != null) {
            T t = null;
            Class<?> clazz = point.getTarget().getClass();
            if(clazz.isAnnotationPresent(type)) {
                t = clazz.getAnnotation(type);
            } else if(method.isAnnotationPresent(type)) {
                t = method.getAnnotation(type);
            }
            return t;
        }
        return null;
    }


    /**
     * 得到类的注解信息
     */
    public static Annotation getClassAnnotation(Class<? extends Annotation> annotationClass, Class<?> type) {
        if(!type.isAnnotationPresent(annotationClass)) {
            return null;
        }
        return type.getAnnotation(annotationClass);
    }

    /**
     * 获取类中所有的方法级别的annoation
     */
    public static List<Annotation> getMethodAnnotations(Class<? extends Annotation> annotationClass, Class<?> type) {
        List<Annotation> annotations = new LinkedList<>();
        for(Method method : type.getDeclaredMethods()) {
            if(!method.isAnnotationPresent(annotationClass)) {
                continue;
            }
            annotations.add(method.getAnnotation(annotationClass));
        }
        return annotations;
    }

    /**
     * 获取annotation的属性值
     */
    public static Object getAnnotationInfo(Annotation annotation , String methodName)
            throws NoSuchMethodException, SecurityException,
            IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        if(annotation == null) {
            return null;
        }
        Method method = annotation.getClass().getDeclaredMethod(methodName, (Class<?>) null);
        return method.invoke(annotation, (Object) null);
    }

}
